from django.shortcuts import render
from django.contrib.auth import authenticate,login,logout
import json

from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from django.views.generic.base import View
from django.contrib.auth.hashers import make_password
from django.http import HttpResponseRedirect,HttpResponse
from django.urls import reverse
#from django.core.paginator import PageNotAnInteger,Paginator
from pure_pagination import PageNotAnInteger, Paginator, EmptyPage

from .models import UserProfile,EmailVerifyRecord,Banner
from .forms import LoginForm,RegisterForm,ForgetPwdForm,ModifyPwdForm,UserInfoForm,UploadImageForm
from movieinfo.models import Movie, MovieParticulars
from operation.models import UserFavorite,UserBrowse
from operation.views import RecommendView

from urils.email_send import send_register_email
from urils.mixin import LoginRequiredMixin

#邮箱和用户名都可以登录
# 基础ModelBackend类，因为它有authenticate方法
class CustomBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            # 不希望用户存在两个，get只能有一个。两个是get失败的一种原因 Q为使用并集查询
            user = UserProfile.objects.get(Q(username=username)|Q(email=username))

            # django的后台中密码加密：所以不能password==password
            # UserProfile继承的AbstractUser中有def check_password(self, raw_password):
            if user.check_password(password):
                return user
        except Exception as e:
            return None


class LoginView(View):
    def get(self,request):
        return render(request,'index.html')


    def post(self,request):
        # 实例化
        login_form=LoginForm(request.POST)
        if login_form.is_valid():
            # 获取用户提交的用户名和密码
            user_name=request.POST.get('username',None)
            pass_word=request.POST.get('password',None)
            # 成功返回user对象,失败返回None
            user=authenticate(username=user_name,password=pass_word)
            # 如果不是null则说明验证成功
            if user is not None:
                if user.is_active:
                    # 登录(只有激活才可以登录)
                    login(request,user)
                    return HttpResponse(json.dumps({'status': 'success'}),content_type='application/json')
                    #return HttpResponseRedirect(reverse('index'))
                else:
                    return HttpResponse(json.dumps({'status': 'failure', 'msg': 'no_active'}), content_type='application/json')
            # 当用户名或密码不存在时，返回错误信息到前端
            else:
                return HttpResponse(json.dumps({'status': 'failure', 'msg': '用户名或密码错误'}), content_type='application/json')
        else:
            return HttpResponse(json.dumps(login_form.errors), content_type='application/json')


# 查看邮箱是否激活的用户
class ActiveUserView(View):
    def get(self,request,active_code):
        # 查询邮箱验证记录是否存在
        all_record=EmailVerifyRecord.objects.filter(code=active_code)

        if all_record:
            for record in all_record:
                # 获取对应邮箱
                email=record.email
                # 查找邮箱对应的user
                user=UserProfile.objects.get(email=email)
                user.is_active=True
                user.save()
                # 激活成功跳转
                return IndexView.get(self,request)
        #验证码不对
        else:
            return render(request,'index.html',{"msg":"您的激活链接无效"})



class RegisterView(View):
    """用户注册"""
    def get(self,request):
        register_form=RegisterForm()
        return render(request,'index.html',{'register_form':register_form})


    def post(self,request):
        register_form= RegisterForm(request.POST)
        if register_form.is_valid():
            user_name= request.POST.get('email','')
            # 如果用户存在则提示错误信息
            if UserProfile.objects.filter(email=user_name):
                # return render(request,'index.html',{'register_form':register_form,'msg':'用户已存在'})
                return HttpResponse("{'register_form':register_form,'msg':'用户已存在'}",content_type='application/json')
            pass_word= request.POST.get('password','')
            # 实例化一个user_profile对象
            user_profile=UserProfile()
            user_profile.username=user_name
            user_profile.email= user_name
            user_profile.is_active= False
            # 对保存到数据库的密码加密
            user_profile.password=make_password(pass_word)
            user_profile.save()
            send_register_email(user_name, 'register')
            return render(request,'index.html')
            # return HttpResponse({'static':'success'},content_type='application/json')
        else:
            # return render(request,'index.html',{'reegister_form': register_form})
            return HttpResponse(json.dumps(register_form.errors),content_type='application/json')


class ForgetPwdView(View):
    """找回密码"""
    def get(self,request):
        forget_form= ForgetPwdForm()
        # return render(request,'index.html',{'forget_form':forget_form})
        return HttpResponse({'forget_form':forget_form})


    def post(self,request):
        forget_form=ForgetPwdForm(request.POST)
        if forget_form.is_valid():
            email=request.POST.get('email',None)
            send_register_email(email,'forget')
            return render(request,'send_success.html')
        else:
            return render(request,'index.html',{'forget_form':forget_form})


class ResetView(View):
    """重置密码"""
    def get(self,request,active_code):
        all_records=EmailVerifyRecord.onjects.filter(code=active_code)
        if all_records:
            for record in all_records:
                email=record.email
                return render(request,'password_reset.html',{'email':email})
        else:
            return render(request,'active_fail.html')
        return render(request,'index.html')


class ModifyPwdView(View):
    """修改密码"""
    def post(self, request):
        modify_form = ModifyPwdForm(request.POST)
        if modify_form.is_valid():
            pwd1 = request.POST.get("password1", "")
            pwd2 = request.POST.get("password2", "")
            email = request.POST.get("email", "")
            if pwd1 != pwd2:
                return render(request, "password_reset.html", {"email":email, "msg":"密码不一致！"})
            user = UserProfile.objects.get(email=email)
            user.password = make_password(pwd2)
            user.save()
            return IndexView.get(self,request)
        else:
            email = request.POST.get("email", "")
            return render(request, "password_reset.html", {"email":email, "modify_form":modify_form })


class LogoutView(View):
    """用户登出"""
    def get(self,request):
        logout(request)
        return HttpResponseRedirect(reverse('index'))


class UserinfoView(LoginRequiredMixin,View):
    """用户个人中心"""
    def According_movie(request,dataTable):
        movie_list = []
        movies = dataTable.objects.filter(user=request.user)
        for movie in movies:
            movie_id = movie.movie_id
            movie = MovieParticulars.objects.get(name_id=movie_id)
            movie_list.append(movie)
        return movie_list

    def get(self,request):
        # 收藏
        fav_list=UserinfoView.According_movie(request,UserFavorite)

        # 历史浏览
        bro_list=UserinfoView.According_movie(request,UserBrowse)

        #推荐
        movie_recommend=RecommendView.recommend(self,request)

        return render(request, 'user.html', {
            'fav_list': fav_list,
            'bro_list': bro_list,
            'movie_recommend': movie_recommend,
        })
        # return render(request,'user.html',)

    def post(self,request):
        user_info_form=UserInfoForm(request.POST, instance=request.user)
        if user_info_form.is_valid():
            print(request.POST.get('birday',''))
            user_info_form.save()
            return HttpResponse('{"status":"success"}',content_type='application/json')
        else:
            return HttpResponse(json.dumps(user_info_form.errors),content_type='application/json')


class UploadImageView(LoginRequiredMixin,View):
    """用户图像修改"""
    def post(self,request):
        # 上传的文件都在request.FILES里面获取,所以这里要多传一个这参数
        image_form=UploadImageForm(request.POST,request.FILES)
        if image_form.is_valid():
            image=image_form.cleaned_data['image']  # 读取image_form中名为image的表单
            request.user.image=image
            request.user.save()
            return HttpResponse('{"status":"success"}',content_type='application/json')
        else:
            return HttpResponse('{"status":"fail"}',content_type='application/json')


class UpdatePwdView(View):
    """个人中心修改用户密码"""
    def post(self,request):
        modify_form=ModifyPwdForm(request.POST)
        if modify_form.is_valid():
            pwd1=request.POST.get("password1","")
            pwd2=request.POST.get("password2","")
            if pwd1 != pwd2:
                return HttpResponse('{"status":"fail","msg":"密码不一致"}',content_type='application/json')
            user=request.user
            user.password=make_password(pwd2)
            user.save()
            # print('成功')
            return HttpResponse('{"status":"success"}',content_type='application/json')
        else:
            return HttpResponse(json.dumps(modify_form.errors),content_type='application/json')


class SendEmailCodeView(LoginRequiredMixin,View):
    """发送邮箱修改验证码"""
    def get(self,request):
        email=request.GET.get('email','')

        if UserProfile.objects.filter(email=email):
            return HttpResponse('{"email":"邮箱已存在"}',content_type='application/json')
        send_register_email(email,'update_email')
        return HttpResponse('{"status":"success"}',content_type='application/json')


class UpdateEmailView(LoginRequiredMixin,View):
    """修改邮箱"""
    def post(self,request):
        email=request.POST.get("email","")
        code=request.POST.get("code","")

        existed_records=EmailVerifyRecord.objects.filter(email=email, code=code, send_type='update_email')
        if existed_records:
            user=request.user
            user.email=email
            user.save()
            return HttpResponse('{"status":"success"}',content_type='application/json')
        else:
            return HttpResponse('{"status":"验证码无效"}',content_type='application/json')


class IndexView(View):
    """首页"""
    def get(self,request):
        # 轮播图
        all_banners=Banner.objects.all().order_by('index')
        # 显示分类
        all_classification= MovieParticulars.objects.all().order_by('id')
        MOVIE_TYPE = {
            'aq': u'爱情',
            'jq': u'剧情',
            'xj': u'喜剧',
            'wx': u'武侠',
            'dz': u'动作',
            'xy': u'悬疑',
            'kb': u'恐怖',
            'fz': u'犯罪',
            'js': u'惊悚',
            'kh': u'科幻',
            'mx': u'冒险',
            'dm': u'动漫',
            'ty': u'体育',
            'jl': u'记录',
            'zz': u'战争'
        }
        REGION = {
            'zg': u'中国',
            'hg': u'韩国',
            'rb': u'日本',
            'om': u'欧美'
        }
        LANGUAGE = {
            'chinese': u'国语',
            'cantonese': u'粤语',
            'japanese': u'日语',
            'korean': u'韩语',
            'english': u'英语',
            'french': u'法语',
            'portuguese': u'葡萄牙语',
            'spanish': u'西班牙语'
        }
        type_dic1, region_dic2, language_dic3 = {}, {}, {}
        for type in all_classification:
            type_dic1[type.movie_type] = MOVIE_TYPE[type.movie_type] if type.movie_type else ''
            region_dic2[type.region] = REGION[type.region] if type.region else ''
            language_dic3[type.language] = LANGUAGE[type.language] if type.language else ''

        # 筛选地区、语言、类型
        region= request.GET.get('region', '')
        if region:
            all_classification = all_classification.filter(region=str(region))
        language= request.GET.get('language', '')
        if language:
            all_classification = all_classification.filter(language=str(language))
        type= request.GET.get('type', '')
        if type:
            all_classification = all_classification.filter(movie_type = str(type))


        # 搜索功能
        search = request.GET.get('search','')
        if search:
            # 这里的搜索只进行了名字和类型的检索
            name = Movie.objects.get(name__icontains= str(search))
            all_classification = all_classification.filter(Q(name=name) | Q(movie_type__icontains=str(search)))

        # 对电影分页(django-pure-pagination )
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        p = Paginator(all_classification, 12, request=request)  # 每页显示12个，从all_classification中取
        movie_page = p.page(page)

        # 点击榜单
        click_nums= Movie.objects.all().order_by('-click_nums')[:10]

        #验证码，
        register_form = RegisterForm()
        # forget_form = ForgetPwdForm()
        return render(request,'index.html',{
            'all_banners':all_banners,
            'register_form': register_form,
            # 'forget_form': forget_form,

            'movie_page': movie_page,
            'type_dic': type_dic1,
            'region_dic': region_dic2,
            'language_dic':language_dic3,

            'movie_region': region,
            'movie_language': language,
            'movie_type': type,

            'click_nums': click_nums,
        })


# def pag_not_found(reqeust):
#     # 全局404处理函数
#     response = render_to_response('404.html', {})
#     response.status_code = 404
#     return response
#
#
# def page_error(request):
#     # 全局500处理函数
#     from django.shortcuts import render_to_response
#     response = render_to_response('500.html', {})
#     response.status_code = 500
#     return response